package com.topnav.mc.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.js.lib.annotation.ApiLogger;
import com.js.lib.cache.SysCache;
import com.js.lib.exception.CustomException;
import com.js.lib.result.Result;
import com.topnav.mc.admin.bean.OrgTreeSelectBean;
import com.topnav.mc.admin.bean.OrgUserVo;
import com.topnav.mc.admin.dao.mapper.OrganizationMapper;
import com.topnav.mc.admin.dao.mapper.UserMapper;
import com.topnav.mc.admin.entity.Organization;
import com.topnav.mc.admin.entity.bean.UserBean;
import com.topnav.mc.admin.entity.param.UserParam;
import com.topnav.mc.admin.entity.wrapper.UserWrapper;
import com.topnav.mc.admin.security.PermissionGrade;
import com.topnav.mc.admin.security.config.JwtProperties;
import com.topnav.mc.admin.security.jwt.utils.JwtTokenUtil;
import com.topnav.mc.admin.service.IOrganizationService;
import com.topnav.mc.base.mc.McController;
import com.topnav.mc.common.Constant;
import com.topnav.mc.exception.ExceptionMsg;
import com.topnav.mc.uitls.ExceptionUtil;
import com.topnav.mc.uitls.PermissionGradeUtil;
import com.topnav.mc.uitls.ResultErrorUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import com.topnav.mc.admin.entity.User;
import com.topnav.mc.admin.service.IUserService;
import io.swagger.annotations.Api;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.topnav.mc.exception.ExceptionMsg.ERROR_AUTHENTICATION_NEW_CONFIRM_PASSWORD_DIFF;

/**
 * 说明：
 * @类名: UserCurdController
 * <p>
 *
 * </p>
 * @author   kenny
 * @Date	 2021年11月19日下午5:57:10
 */
@Api(value = "admin/user", tags = "用户管理")
@RestController
@CrossOrigin
@RequestMapping("admin/user")
@Slf4j
//public class UserController extends CurdController<User, IUserService> {
public class UserController extends McController<User, UserBean, UserParam, IUserService, UserWrapper> {
	@Resource
	private JwtProperties jwtProperties;
	@Resource
	private JwtTokenUtil jwtTokenUtil;

	@Autowired
	private IOrganizationService organizationService;
	@Autowired
	private OrganizationMapper organizationMapper;

	@Autowired
	private IUserService userService;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private PermissionGradeUtil permissionGradeUtil;
	//@Resource
	@Autowired
	private PasswordEncoder passwordEncoder;

	/**
	 * 修改密码
	 * @param request
	 * @param userParam
	 * @return
	 */
	@ApiOperation("修改密码")
	@PostMapping("/change/password")
	@ApiLogger(apiName="/admin/user/change/password")
	@ResponseBody
	public Result changePassword(HttpServletRequest request, @RequestBody UserParam userParam) {
		if (userService.changePassword(userParam)){
			return Result.ok();
		}else{
			log.error("修改密码失败！");
			return ResultErrorUtil.byExceptionMsg(ExceptionMsg.ERROR_AUTHENTICATION_CHANGE_PASSWORD_FAILED);
		}
	}

	@GetMapping("/current/user")
	@ApiLogger(apiName="/admin/user/current/user")
	@ResponseBody
	public Result currentUser() {
		PermissionGrade permissionGrade = permissionGradeUtil.getPmGradeCheck();
		if (permissionGrade == null){
			return ResultErrorUtil.byExceptionMsg(ExceptionMsg.ERROR_AUTHENTICATION_FAILE);
		}
		if ("super".equals(permissionGrade.getUserName())){
			UserBean userBean = new UserBean();
			userBean.setLoginName(permissionGrade.getUserName());
			userBean.setCode(permissionGrade.getUserName());
			userBean.setName(permissionGrade.getUserName());
			userBean.setEnabled(true);
			userBean.setEnabledNotify(true);
			userBean.setMaxRoleLevel(4);

			return Result.ok(userBean);
		}
		QueryWrapper<UserParam> queryWrapper = new QueryWrapper<UserParam>().eq("u.id",permissionGrade.getUserId());
		return Result.ok(userService.getOneInfo(queryWrapper,false));
	}

	/**
	 * 允许通知
	 * @param user
	 * @return
	 */
	@PostMapping("/enabled/notify")
	@ApiLogger(apiName="/admin/user/enabled/notify")
	@ResponseBody
	public Result enabledNotify(@RequestBody User user) {
		PermissionGrade permissionGrade = permissionGradeUtil.getPmGradeCheck();
		if (permissionGrade == null){
			return ResultErrorUtil.byExceptionMsg(ExceptionMsg.ERROR_AUTHENTICATION_EFFE);
		}
		permissionGrade.setEnabledNotify(user.getEnabledNotify());
		UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
		updateWrapper.set("enabled_notify",user.getEnabledNotify()).eq("id",permissionGrade.getUserId());
		if (userService.update(updateWrapper)){
			return Result.ok();
		}else{
			log.error(">>>>>> close alarm notity failed");
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DISABLED_ALARM_NOTIFY_FAILED);
		}

	}


	/**
	 *  由path做为参数取得上级单位
	 * @param list
	 * @param path
	 * @return
	 */

	private List<OrgTreeSelectBean> getFromChildren(List<OrgTreeSelectBean> list, String path){
		String ids[] = path.split("/");
		for(int i=0;i<ids.length;i++) {
			list = getFromChildren(list,Long.valueOf(ids[i]));
			if (i==ids.length-1) {
				return list;
			}
		}
		return list;
	}
	/**
	 * 由id为参数传入
	 * 在 children查找，没有则创建
	 * @param list
	 * @param id
	 * @return
	 */
	private List<OrgTreeSelectBean> getFromChildren(List<OrgTreeSelectBean> list, Long id){
		for(OrgTreeSelectBean o: list){
			if (id.equals(o.getId())){
				return o.getChildren();
			}
		}
		Organization o = organizationService.getById(id);
		OrgTreeSelectBean ol=new OrgTreeSelectBean().setId("O_"+o.getId().toString()).setPath(o.getPath()).setLabel(o.getShortName());
		ol.getArrt().put("type","org");
		ol.setChildren(new ArrayList<OrgTreeSelectBean>());
		list.add(ol);
		return ol.getChildren();
	}
	/**
	 * 密码重置
	 * @param request
	 * @param userParam
	 * @return
	 */
	@ApiOperation("密码重置")
	@PostMapping("/reset/password")
	@ApiLogger(apiName="/admin/user/reset/password")
	@ResponseBody
	public Result resetPassword(HttpServletRequest request, @RequestBody UserParam userParam) {
		PermissionGrade permissionGrade = permissionGradeUtil.getPmGrade();

		if (permissionGrade.getPermissionLevel() < 4){
			//throw new CustomException(ExceptionMsg.ERROR_AUTHENTICATION_RESET_PASSWORD_NOADMIN);
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_AUTHENTICATION_RESET_PASSWORD_NOADMIN);
		}

		/** 更新密码 */
		UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>()
				.set("password",passwordEncoder.encode("88888888"))
				.eq("id",userParam.getId());

		if (userService.update(updateWrapper)){
			log.info(">>>>>> user {} reset password succeed！", userParam.getName());
			return Result.ok();
		}else{
			log.error(">>>>>> 重置密码失败");
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_AUTHENTICATION_RESET_PASSWORD_FAILED);
		}
	}
	/**
	 * 查询用户包含上级机构
	 * 给前端 TreeSelect使用
	 * */
	@ApiLogger(apiName="admin/user/searchByOrgPath")
	@ApiOperation(value = "查询用户包含上级机构")
	@ApiImplicitParams(
			{@ApiImplicitParam(name="path", value = "机构path", required=false,dataTypeClass = Long.class),
			 @ApiImplicitParam(name="value", value = "输入值", required=false,dataTypeClass = Long.class)})
	@PostMapping("/query/searchByOrgPath")
	@ResponseBody
	public Result searchByOrgPath(@RequestBody Map<String,Object> param){
		List<OrgTreeSelectBean> treeSelects = new ArrayList<OrgTreeSelectBean>();
		List<OrgUserVo> users = userMapper.searchByOrgPath(param);
		List<OrgTreeSelectBean> children=null;
		OrgTreeSelectBean ol=null;
		for(OrgUserVo u : users){
			children = getFromChildren(treeSelects,u.getOrgPath());
			ol = new OrgTreeSelectBean()
					.setId("U_" + u.getId().toString())
					.setPath(u.getOrgPath())
					.setLabel(u.getCode() + ' ' + u.getName() )
					.setParentId(u.getId());
			ol.getArrt().put("type","user");
			children.add(ol);
		}
		return Result.ok(treeSelects);
	}





}
